#!/bin/bash
#
# Fedora-native mktree backend using DNF to bootstrap a minimal OS tree with
# the RPM runtime and test dependencies but no stock RPM preinstalled.
# Lightweight snapshotting built into the test-suite is used for isolation.

source ./mktree.common

OUT_DIR=$PWD/mktree.output
BASE_DIR=$OUT_DIR/base
INST_DIR=$OUT_DIR/inst
SANDBOX_DIR=$PWD/mktree.sandbox
CACHE_DIR=$PWD/mktree.cache

RPM_MACROS="
%_netsharedpath %{nil}
%__transaction_systemd_inhibit %{nil}
"

ENV_MOTD="
Welcome to RPM test environment!

This is like an interactive test but with
full host integration.

Your test tree is mounted at \$RPMTEST.
You can use the usual test commands, e.g.

  runroot rpm ...

DNF is set to operate on the tree, use it
simply like this:

  dnf install ...
"

CMD=$1; shift

mount_tree()
{
    source ./atlocal
    RPMTREE=$INST_DIR:$BASE_DIR
    RPMTEST=${1:-$OUT_DIR}/tree
    trap "snapshot umount" EXIT
    snapshot mount $1
}

# Run CMD in a user namespace (if not root already)
if [ $(id -u) != 0 ]; then
    if [ -f /run/.toolboxenv ]; then
        # toolbox(1) support
        UNSHARE="sudo --preserve-env"
    else
        UNSHARE="unshare -r --mount --map-auto"
    fi
    $UNSHARE $0 $CMD "$@"
    exit
fi

case $CMD in
    build)
        rm -rf "$INST_DIR"
        make_install $INST_DIR

        [ -d "$BASE_DIR" ] && exit 0

        mkdir -p $CACHE_DIR
        echo "$RPM_MACROS" > $CACHE_DIR/.rpmmacros

        HOME=$CACHE_DIR \
        dnf install -y \
            --installroot=$BASE_DIR \
            --releasever=@OS_VERSION@ \
            --setopt=cachedir=$CACHE_DIR/dnf \
            --setopt=keepcache=1 \
            --setopt=install_weak_deps=0 \
            --disablerepo=\* --enablerepo=fedora,updates \
            --exclude=rpm,systemd-udev \
            bash \
            binutils \
            bubblewrap \
            bzip2 \
            coreutils \
            cpio \
            curl \
            debugedit \
            diffutils \
            elfutils-libelf \
            elfutils-libs \
            file \
            file-libs \
            findutils \
            gawk \
            gcc \
            gdb-minimal \
            glibc \
            gpg \
            grep \
            gzip \
            ima-evm-utils \
            libacl \
            libarchive \
            libcap \
            libfsverity \
            libgomp \
            libzstd \
            lua-libs \
            make \
            openssl-libs \
            patch \
            pkgconf-pkg-config \
            popt \
            python3 \
            rpm-sequoia \
            sed \
            shadow-utils \
            sqlite-libs \
            tar \
            unzip \
            util-linux-core \
            which \
            xz \
            xz-libs \
            zlib \
            zstd

        # Point RPM to newly created database
        echo "%_dbpath $(rpm --eval '%_dbpath')" > $BASE_DIR/root/.rpmmacros

        # Configure default shell for root user
        cp -r $BASE_DIR/{etc/skel/.,/root}
    ;;
    env)
        set -a
        mount_tree $SANDBOX_DIR
        function dnf() {
            /usr/bin/dnf --installroot=$RPMTEST "$@"
        }
        echo "$ENV_MOTD"
        $SHELL
        exit 0
    ;;
    shell)
        mount_tree $SANDBOX_DIR
        snapshot shell "$@"
        exit 0
    ;;
    check)
        mount_tree
        snapshot shell --tmpfs /tmp --chdir /srv ./rpmtests "$@"
    ;;
    reset)
        rm -rf "$SANDBOX_DIR"
    ;;
esac
